package com.jic.veteran.service.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.ZipUtil;
import cn.hutool.poi.excel.ExcelUtil;
import com.jic.veteran.common.pay.SybUtil;
import com.jic.veteran.dao.DonatePayDetailDao;
import com.jic.veteran.mapper.ProjectDonationDetailMapper;
import com.jic.veteran.mapper.ReconDetailMapper;
import com.jic.veteran.mapper.ReconResultMapper;
import com.jic.veteran.model.DonatePayDetail;
import com.jic.veteran.model.ProjectDonationDetail;
import com.jic.veteran.model.ReconDetail;
import com.jic.veteran.model.ReconResult;
import com.jic.veteran.service.DonatePayService;
import com.jic.veteran.service.DonationReconService;
import com.jic.veteran.service.UmsAdminCacheService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Slf4j
@Service
public class DonationReconServiceImpl implements DonationReconService {
    @Autowired
    private ProjectDonationDetailMapper projectDonationDetailMapper;
    @Autowired
    private DonatePayDetailDao donatePayDetailDao;
    @Autowired
    private UmsAdminCacheService umsAdminCacheService;
    @Autowired
    private ReconDetailMapper reconDetailMapper;
    @Autowired
    private ReconResultMapper reconResultMapper;
    @Autowired
    private DonatePayService donatePayService;
    @Value("${recon.file.path}")
    private String RECON_FILE_PATH;

    @Override
    public String payQuery(String reqsn, String trxid) throws Exception{
        Map<String, String> queryResult = null;
        try {
//            queryResult = SybPayUtil.query(reqsn, trxid);
            queryResult = donatePayService.query(reqsn, trxid);
        } catch (Exception e) {
            log.info("交易查询出现错误:{}",e.getMessage());
        }
        if(null != queryResult) {
            String retcode = queryResult.get("retcode");
            String trxstatus = queryResult.get("trxstatus");
            if(StrUtil.isNotEmpty(retcode) && StrUtil.isNotEmpty(trxstatus)) {
                if("SUCCESS".equals(retcode) && "0000".equals(trxstatus)) {
                    DonatePayDetail donatePayDetail = donatePayDetailDao.getItemByReqsn(reqsn);
                    if(null != donatePayDetail) {
                        List<DonatePayDetail> donatePayedDetails = donatePayDetailDao.getItemByTrxidByStatus(trxid,"1");
                        if(donatePayedDetails.isEmpty()) {
                            donatePayDetail.setPayStatus("1");
                            donatePayDetail.setTrxdate(DateUtil.format(DateUtil.date(),"yyyy-MM-dd"));
                            donatePayDetail.setFintime(queryResult.get("paytime"));
                            int result = donatePayDetailDao.insert(donatePayDetail);
                            ProjectDonationDetail projectDonationDetail = new ProjectDonationDetail();
                            projectDonationDetail.setProjectId(donatePayDetail.getProjectId());
                            projectDonationDetail.setProjectName(donatePayDetail.getProjectName());
                            projectDonationDetail.setDonationAmount(donatePayDetail.getTrxamt());
                            projectDonationDetail.setDonationTime(DateUtil.date());
                            projectDonationDetail.setUserId(donatePayDetail.getOpenid());
                            projectDonationDetail.setReqsn(donatePayDetail.getReqsn());
                            projectDonationDetail.setCreateTime(DateUtil.date());
                            projectDonationDetail.setCreateBy(donatePayDetail.getOpenid());
                            result = projectDonationDetailMapper.insert(projectDonationDetail);
                            if(result > 0) {
                                umsAdminCacheService.lPushLimit(projectDonationDetail);
                                return "success";
                            }
                        }
                    }
                }
            }
        }
        return "fail";
    }

    /**
     * 下载对账文件
     * @return
     * @throws Exception
     */
    @Override
    public String getUrl(String custId,String date) throws Exception{
        String rjqCount;
        String rjqAmt;
        String reconCount;
        String reconAmt;
        String url = null;
        int sheetNum = 0;
        try {
//            url = SybPayUtil.getUrl(custId,date);
            url = donatePayService.getUrl(date,custId);
        } catch (Exception e) {
            log.info("获取对账文件地址出现错误:{}",e.getMessage());
            ReconResult reconResult = new ReconResult();
            reconResult.setReconDate(date);
            reconResult.setResult(e.getMessage());
            reconResultMapper.insert(reconResult);
        }
        File fileDown = null;
        if(StrUtil.isNotEmpty(url)) {
            try {
                fileDown = SybUtil.downLoad(url, RECON_FILE_PATH, custId);
            } catch (IOException e) {
                log.info("下载对账文件地址出现错误:{}",e.getMessage());
            }
        }
        if(null !=fileDown) {
            File unzip = ZipUtil.unzip(fileDown);
            log.info("解压后的文件:{}",unzip.getAbsolutePath());
            ReconResult reconResult = new ReconResult();
            reconResult.setReconDate(date);
            reconResult.setReconFile(unzip.getAbsolutePath());
            reconResult.setResult("对账处理中");
            reconResultMapper.insert(reconResult);
            Long insert =reconResult.getId();
            List<List<Object>> total = ExcelUtil.getReader(unzip.getAbsolutePath()+"/"+custId+".xlsx",0).read(4);
            for (List<Object> list:total) {
                if(ObjectUtil.isNotEmpty(list.get(4)) && String.valueOf(list.get(4)).equals("汇总")) {
                    log.info("对账文件交易汇总，交易金额:{},交易笔数:{}",list.get(5),list.get(6));
                    rjqCount = String.valueOf(list.get(5));
                    rjqAmt = String.valueOf(list.get(6));
                    break;
                }
                sheetNum++;
            }
            Map<String,String> sumTotal = donatePayDetailDao.getSumTotalForRecon(DateUtil.parse(date,"yyyyMMdd").toString("yyyy-MM-dd"));
            if(null != sumTotal) {
                log.info("荣军情交易汇总，交易金额:{},交易笔数:{}",sumTotal.get("sum_amt"),sumTotal.get("sum_count"));
                reconCount = String.valueOf(sumTotal.get("sum_count"));
                reconAmt = String.valueOf(sumTotal.get("sum_amt"));
            }
            List<List> details = new ArrayList<List>();
            for (int i = 1; i <= sheetNum; i++) {
                List<List<Object>> sheetDetails = ExcelUtil.getReader(unzip.getAbsolutePath()+"/"+custId+".xlsx",i).read(10);
                for (List list:sheetDetails) {
                    details.add(list);
                }
            }
            if (!details.isEmpty() && details.size() >3) {
                for (int i=0; i<details.size()-3; i++) {
                    log.info("交易时间:{},交易金额:{},交易日期:{},交易单号trxid:{},订单号reqsn:{}",details.get(i).get(1),details.get(i).get(9),
                            details.get(i).get(11),details.get(i).get(12),details.get(i).get(13));
                }
            }

            List<DonatePayDetail> donatePayDetails = donatePayDetailDao.getItemsForRecon(DateUtil.parse(date,"yyyyMMdd").toString("yyyy-MM-dd"));
            for (DonatePayDetail donatePayDetail:donatePayDetails) {
                log.info("交易时间:{},交易金额:{},交易日期:{},交易单号trxid:{},订单号reqsn:{}",donatePayDetail.getFintime(),donatePayDetail.getTrxamt(),
                        donatePayDetail.getTrxdate(),donatePayDetail.getReqsn(),donatePayDetail.getTrxid());
            }
            StringBuffer reconResultStr = new StringBuffer();
            if (!details.isEmpty() && details.size() >3) {
                for (int i=0; i<details.size()-3; i++) {
                    boolean result = false;
                    DonatePayDetail donatePayDetail = donatePayDetailDao.getItemForRecon((String) details.get(i).get(12), (String) details.get(i).get(13));
                    if(null != donatePayDetail) {
                        result = StrUtil.equals(donatePayDetail.getTrxdate(), (String) details.get(i).get(11)) && NumberUtil.equals(donatePayDetail.getTrxamt(), NumberUtil.toBigDecimal((String) details.get(i).get(9)))
                                && StrUtil.equals(donatePayDetail.getTrxid(), (String) details.get(i).get(12)) && StrUtil.equals(donatePayDetail.getReqsn(), (String) details.get(i).get(13));
                        log.info("对账文件基准,交易时间:{},交易金额:{},交易日期:{},交易单号trxid:{},订单号reqsn:{},对账结果:{}",details.get(i).get(1),details.get(i).get(9),
                                details.get(i).get(11),details.get(i).get(12),details.get(i).get(13),result);
                        if(!result) {
                            reconResultStr.append(String.format("对账文件基准,交易日期:%s,交易单号trxid:%s订单号reqsn:%s\n",details.get(i).get(11),details.get(i).get(12),details.get(i).get(13)));
                            ReconDetail reconDetail = new ReconDetail();
                            reconDetail.setReconDate((String) details.get(i).get(11));
                            reconDetail.setReconAmt(NumberUtil.toBigDecimal((String) details.get(i).get(9)));
                            reconDetail.setReconTrxid((String) details.get(i).get(12));
                            reconDetail.setReconReqsn((String) details.get(i).get(13));
                            if(null != donatePayDetail) {
                                reconDetail.setRjqDate(donatePayDetail.getTrxdate());
                                reconDetail.setRjqAmt(donatePayDetail.getTrxamt());
                                reconDetail.setRjqTrxid(donatePayDetail.getTrxid());
                                reconDetail.setRjqReqsn(donatePayDetail.getReqsn());
                            }
                            reconDetail.setReconDirection("1");
                            reconDetail.setReconId(insert);
                            reconDetailMapper.insert(reconDetail);
                        }
                    }
                }
                log.info("对账文件基准,差异明细:{}",StrUtil.isNotEmpty(reconResultStr.toString()) ? reconResultStr.toString() : "无");
            }
            for (int i=0;i<donatePayDetails.size();i++) {
                boolean result = false;
                DonatePayDetail donatePayDetail = donatePayDetails.get(i);
                boolean isExist = false;
                for (int j=0; j<details.size()-3; j++) {
                    if(StrUtil.equals(donatePayDetail.getTrxid(), (String) details.get(j).get(12)) && StrUtil.equals(donatePayDetail.getReqsn(), (String) details.get(j).get(13))) {
                        isExist = true;
                        result = StrUtil.equals(donatePayDetail.getTrxdate(), (String) details.get(j).get(11)) && NumberUtil.equals(donatePayDetail.getTrxamt(), NumberUtil.toBigDecimal((String) details.get(j).get(9)));
                        if(!result) {
                            reconResultStr.append(String.format("荣军情交易基准,交易日期:%s,交易单号trxid:%s订单号reqsn:%s\n",donatePayDetail.getTrxamt(),donatePayDetail.getTrxid(),donatePayDetail.getReqsn()));
                            ReconDetail reconDetail = new ReconDetail();
                            reconDetail.setReconDate((String) details.get(i).get(11));
                            reconDetail.setReconAmt(NumberUtil.toBigDecimal((String) details.get(i).get(9)));
                            reconDetail.setReconTrxid((String) details.get(i).get(12));
                            reconDetail.setReconReqsn((String) details.get(i).get(13));
                            reconDetail.setRjqDate(donatePayDetail.getTrxdate());
                            reconDetail.setRjqAmt(donatePayDetail.getTrxamt());
                            reconDetail.setRjqTrxid(donatePayDetail.getTrxid());
                            reconDetail.setRjqReqsn(donatePayDetail.getReqsn());
                            reconDetail.setReconDirection("2");
                            reconDetail.setReconId(insert);
                            reconDetailMapper.insert(reconDetail);
                        }
                    }
                }
                if(!isExist) {
                    reconResultStr.append(String.format("荣军情交易基准,交易日期:%s,交易单号trxid:%s订单号reqsn:%s\n",donatePayDetail.getTrxamt(),donatePayDetail.getTrxid(),donatePayDetail.getReqsn()));
                    ReconDetail reconDetail = new ReconDetail();
                    reconDetail.setRjqDate(donatePayDetail.getTrxdate());
                    reconDetail.setReconAmt(donatePayDetail.getTrxamt());
                    reconDetail.setReconTrxid(donatePayDetail.getTrxid());
                    reconDetail.setReconReqsn(donatePayDetail.getReqsn());
                    reconDetail.setReconDirection("2");
                    reconDetail.setReconId(insert);
                    reconDetailMapper.insert(reconDetail);
                }
                log.info("荣军情交易基准,交易时间:{},交易金额:{},交易日期:{},交易单号trxid:{},订单号reqsn:{},对账结果:{}",donatePayDetail.getFintime(),donatePayDetail.getTrxamt(),
                        donatePayDetail.getTrxdate(),donatePayDetail.getReqsn(),donatePayDetail.getTrxid(),result);
            }
            log.info("荣军情交易基准,差异明细:{}",StrUtil.isNotEmpty(reconResultStr.toString()) ? reconResultStr.toString() : "无");
            reconResultMapper.updateReconResult(insert,StrUtil.isNotEmpty(reconResultStr.toString()) ? "对账出现偏差" : "对账成功");
        }
        return url;
    }
}
